import math
import os
import pandas as pd
import numpy as np
import datetime
import statsmodels.api as sm
import Core.Config as Config
import matplotlib.pyplot as plt
from SystematicFactors.General import Save_Systematic_Factor_To_Database


# 计算基钦周期，采用bp滤波做法
def BP_Method_Filter(var):
    lag_var = var.shift(52) #滞后52周即一年的数据
    # raw_data = (np.log(var) - np.log(lag_var)).dropna()
    raw_data = (var/lag_var - 1).dropna()
    cf_cycles, cf_trend = sm.tsa.filters.cffilter(raw_data, low=130, high=234)
    return cf_cycles


def Calc_Kitchin_Cycle(database, datetime2, period="Weekly"):
    #
    datetime1 = datetime.datetime(1993, 1, 1)
    df = database.Get_Daily_Bar_DataFrame("000001.SH",
                                          instrument_type="index",
                                          projection=["date", "close"],
                                          datetime1=datetime1,
                                          datetime2=datetime2)

    df.index = pd.to_datetime(df["date"])
    df_weekly = df.resample('W').last()
    df_weekly.dropna(inplace=True)
    df_weekly = df_weekly[["close"]]
    #
    print(df_weekly)
    print(len(df_weekly))

    #
    res = BP_Method_Filter(df_weekly)
    # dict_data = {'date': res.index, 'Kitchin_Cycle_SH': res.values}
    # df_factor = pd.DataFrame(dict_data)
    df_factor = res.to_frame(name="Cycle")
    # print(df_factor)

    if period == "Monthly":
        df_factor = df_factor.resample('M').last().fillna(method='ffill')
    else:
        df_factor = df_factor.resample('W').last().fillna(method='ffill')

    #
    # print(df_factor)
    # df_factor.plot(y="Cycle")
    # plt.show()

    # Kitchin_Cycle_Weekly
    Save_Systematic_Factor_To_Database(database, df_factor, save_name="Kitchin_Cycle_" + period, field_name="Cycle")


if __name__ == '__main__':
    #
    # from Core.Config import *
    # pathfilename = os.getcwd() + "\..\Config\config2.json"
    # config = Config(pathfilename)
    # database = config.DataBase("JDMySQL")
    # realtime = config.RealTime()
    #
    path_filename = os.getcwd() + "\..\Config\config_local.json"
    database = Config.create_database(database_type="MySQL", config_file=path_filename, config_field="MySQL")
    #
    datetime1 = datetime.datetime(2000, 1, 1)
    datetime2 = datetime.datetime(2024, 4, 30)
    #
    Calc_Kitchin_Cycle(database, datetime2, period="Weekly")
    Calc_Kitchin_Cycle(database, datetime2, period="Monthly")
